/*
 * @Author: wangcb
 * @Email: wangcbgg@163.com
 * @Date: 2021-08-27 18:02:35
 * @LastEditTime: 2021-10-21 18:12:36
 * 常用工具函数
 */
// 单实例防抖节流timer
let debounceTimer = 0, throttleTimer = 0;
/**
 * 是否支持某个css3属性
 * @param {string} prop 待检测属性
 * @returns {boolean} 是否支持
 */
export function supportCss3(prop) {
    const div = document.createElement('div');
    const vendors = 'Ms O Moz Webkit'.split(' ');
    let len = vendors.length;
    if (prop in div.style)
        return true;
    prop = prop.replace(/^[a-z]/, val => val.toUpperCase());
    while (len--) {
        if (vendors[len] + prop in div.style)
            return true;
    }
    return false;
}
/**
 * 判断obj是否是给定类型
 * @param {TType} type 数据类型
 * @param {*} obj 目标对象
 * @returns {boolean} obj是否是给定类型
 * @example
 * let obj = [1, 2, 3];
 * typeIs('Array', obj);// true
 * let a = 1;
 * typeIs('Number', a);// true
 */
export function typeIs(type, obj) {
    if (type === 'Number' && typeof obj === 'number')
        return !isNaN(obj) && Infinity !== obj && -Infinity !== obj;
    return Object.prototype.toString.call(obj) === `[object ${type}]`;
}
/**
 * 单实例函数防抖
 * @param {Function} fn 待执行函数
 * @param {number} [interval=1000] 响应间隔（默认1000）
 * @example
 * debounce(() => {console.log('print');}, 1000);
 */
export function debounce(fn, interval = 1000) {
    if (debounceTimer)
        clearTimeout(debounceTimer), debounceTimer = 0;
    debounceTimer = setTimeout(() => {
        clearTimeout(debounceTimer), fn?.();
    }, interval);
}
/**
 * 取消单实例函数防抖
 * @example
 * cancelDebounce();
 */
export function cancelDebounce() {
    if (debounceTimer)
        clearTimeout(debounceTimer), debounceTimer = 0;
}
/**
 * 单实例函数节流
 * @param {Function} fn 待执行函数
 * @param {number} [interval=1000] 响应间隔（默认1000）
 * @example
 * throttle(() => {console.log('print');}, 1000, true);
 */
export function throttle(fn, interval = 1000) {
    if (!throttleTimer) {
        throttleTimer = setTimeout(() => {
            clearTimeout(throttleTimer), throttleTimer = 0, fn?.();
        }, interval);
    }
}
/**
 * 取消单实例函数节流
 * @example
 * cancelThrottle();
 */
export function cancelThrottle() {
    if (throttleTimer)
        clearTimeout(throttleTimer), throttleTimer = 0;
}
/**
 * 函数防抖生成器
 * @param {Function} fn 待执行函数
 * @param {number} [interval=1000] 响应间隔（默认1000）
 * @param {boolean} [immediate] 是否立即执行
 * @example
 * const fn = debounceBuilder(() => {console.log('print');}, 1000, true);
 * fn();// 立即执行
 * fn.cancel();// 取消防抖
 */
export function debounceBuilder(fn, interval = 1000, immediate) {
    let timer = 0, clear = () => { if (timer)
        clearTimeout(timer), timer = 0; };
    const d = (...args) => {
        if (immediate) {
            if (timer) {
                clearTimeout(timer), timer = 0;
            }
            else {
                fn.apply(d, args);
            }
            timer = setTimeout(() => { clear(); }, interval);
        }
        else {
            clear(), timer = setTimeout(() => {
                clear(), fn.apply(d, args);
            }, interval);
        }
    };
    /** 取防抖流 */
    d.cancel = clear;
    return d;
}
/**
 * 函数节流生成器
 * @param {Function} fn 待执行函数
 * @param {number} [interval=1000] 响应间隔（默认1000）
 * @param {boolean} [immediate] 是否立即执行
 * @example
 * const fn = throttleBuilder(() => {console.log('print');}, 1000, true);
 * fn();// 立即执行
 * fn.cancel();// 取消节流
 */
export function throttleBuilder(fn, interval = 1000, immediate) {
    let timer = 0, clear = () => { if (timer)
        clearTimeout(timer), timer = 0; };
    const t = (...args) => {
        if (!timer) {
            if (immediate) {
                fn.apply(t, args);
            }
            timer = setTimeout(() => {
                clear(), !immediate && fn.apply(t, args);
            }, interval);
        }
    };
    /** 取消节流 */
    t.cancel = clear;
    return t;
}
